package server

import (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"sync"
	"time"

	pb "proto"
)

var ErrMatchTimeout = errors.New("match timeout")

const (
	BOT_ID_PREFIX = "bot_"
)

type MatchMaker struct {
	mu           sync.Mutex
	waitingQueue map[string]*MatchRequest // playerID -> matchRequest
	matchTimeout time.Duration
}

type MatchRequest struct {
	PlayerID   string
	Formation  []*pb.HeroPosition
	ResultChan chan string
}

type MatchResult struct {
	OpponentID        string
	OpponentFormation []*pb.HeroPosition
}

func NewMatchMaker() *MatchMaker {
	return &MatchMaker{
		waitingQueue: make(map[string]*MatchRequest),
		matchTimeout: 60 * time.Second,
	}
}

// StartMatch 开始匹配
func (mm *MatchMaker) StartMatch(playerID string, formation []*pb.HeroPosition) (*MatchResult, error) {
	mm.mu.Lock()

	// 检查等待队列中是否有其他玩家
	for otherID, otherReq := range mm.waitingQueue {
		// 不与机器人匹配
		if isBot(otherID) {
			continue
		}
		// 找到对手，从等待队列中移除
		delete(mm.waitingQueue, otherID)
		mm.mu.Unlock()

		// 通知对手匹配成功
		otherReq.ResultChan <- playerID
		close(otherReq.ResultChan)

		return &MatchResult{
			OpponentID:        otherID,
			OpponentFormation: otherReq.Formation,
		}, nil
	}

	// 如果没有真实玩家，创建机器人
	botID := generateBotID()
	log.Printf("No players in queue, matching with bot: %s", botID)
	mm.mu.Unlock()
	return &MatchResult{
		OpponentID:        botID,
		OpponentFormation: formation, // 机器人使用相同的阵容
	}, nil
}

// 生成机器人ID
func generateBotID() string {
	return fmt.Sprintf("%s%d", BOT_ID_PREFIX, rand.Intn(10000))
}

// 判断是否是机器人ID
func isBot(playerID string) bool {
	return len(playerID) > len(BOT_ID_PREFIX) && playerID[:len(BOT_ID_PREFIX)] == BOT_ID_PREFIX
}

// CancelMatch 取消匹配
func (mm *MatchMaker) CancelMatch(playerID string) {
	mm.mu.Lock()
	defer mm.mu.Unlock()

	if ch, exists := mm.waitingQueue[playerID]; exists {
		delete(mm.waitingQueue, playerID)
		close(ch.ResultChan)
	}
}
